#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QJsonObject>
#include <QJsonDocument>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //打开摄像头
    cap.open(0);//dev/video

    //启动定时器事件
    startTimer(100);

    //导入级联分类器文件
    cascade.load("E:/opencv/build/install/etc/haarcascades/haarcascade_frontalface_alt2.xml");

    // //QTcpSocket当断开连接的时候会发送disconnected信号,连接成功会发送connected
    // connect(&m_socket,&QTcpSocket::disconnected,this,&MainWindow::start_connect);
    // connect(&m_socket,&QTcpSocket::connected,this,&MainWindow::stop_connect);

    // //定时器连接服务器
    // connect(&m_timer,&QTimer::timeout,this,&MainWindow::timer_connect);

    //连接服务器
    initConnections();
    //启动定时器
    m_timer.start(5000);//每5秒连接一次，直到连接成功

    flag=0;

    ui->Success_widget->hide();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::timerEvent(QTimerEvent *ev)
{
    //采集数据
    Mat srcImage;
    if(cap.grab())
    {
        cap.read(srcImage);//读取一帧数据
    }

    //把图片大小设与显示窗口一样大
    cv::resize(srcImage,srcImage,Size(480,480));

    Mat grayImage;
    //转灰度图
    cvtColor(srcImage,grayImage,COLOR_BGR2GRAY);
    //检测人脸数据
    std::vector<Rect>faceRects;

    cascade.detectMultiScale(grayImage,faceRects);//检测人脸
    if(faceRects.size()>0&&flag>=0)
    {

        Rect rect=faceRects.at(0);//第一个人脸的矩形框
        // rectangle(srcImage,rect,Scalar(0,0,255));

        //移动人脸框(QLabel)
        ui->headppic_lb->move(rect.x-60,rect.y-50);

        if(flag>2){
        //把Mat数据转化为QbyteArray,-->编码成jpg格式再发送
        std::vector<uchar> buf;
        cv::imencode(".jpg",srcImage,buf);
        QByteArray byte((const char*)buf.data(),buf.size());

        //准备发送
        qint64 backsize=byte.size();
        QByteArray sendData;
        QDataStream stream(&sendData,QIODevice::WriteOnly);
        stream.setVersion(QDataStream::Qt_6_5);
        stream<<backsize<<byte;

        //发送
        m_socket.write(sendData);
        flag=-2;

        qDebug()<<"发送";
        faceMat=srcImage(rect);

        //保存
        imwrite("./face.jpg",faceMat);
        }
        flag++;
    }
    if(faceRects.size()==0)
    {
        //把人脸框移动到中心位置
        ui->headppic_lb->move(100,60);
        ui->Success_widget->hide();
        flag=0;
    }

    if(srcImage.data==nullptr)
        return;

    //把opencv里面的Mat格式数据(BGR)转qt里的QImage(RGB)
    cvtColor(srcImage,srcImage,COLOR_BGR2RGB);
    QImage image(srcImage.data,srcImage.cols,srcImage.rows,srcImage.step1(),QImage::Format_RGB888);
    QPixmap mmp=QPixmap::fromImage(image);

    ui->vdieo_lb->setPixmap(mmp);
}

void MainWindow::timer_connect()
{
    //连接服务器
    m_socket.connectToHost("192.168.88.234",9999);
    qDebug()<<"正在连接";
}

void MainWindow::stop_connect()
{
    m_timer.stop();
    qDebug()<<"成功连接";
}

void MainWindow::start_connect()
{
    m_timer.start(5000);//启动定时器
}

void MainWindow::recv_data()
{
    //
    QByteArray array=m_socket.readAll();
    qDebug()<<array;
    //qDebug()<<msg;
    //ui->lineEdit->setText(msg);

    //Json解析
    QJsonParseError err;
    QJsonDocument doc=QJsonDocument::fromJson(array,&err);
    if(err.error!=QJsonParseError::NoError)
    {
        qDebug()<<"json数据错误";
        return;
    }
    QJsonObject obj=doc.object();
    QString employeeID=obj.value("employeeID").toString();
    QString name=obj.value("name").toString();
    QString department=obj.value("department").toString();
    QString timestr=obj.value("time").toString();

    ui->numberEdit->setText(employeeID);
    ui->nameEdit->setText(name);
    ui->departmentEdit->setText(department);
    ui->timeEdit->setText(timestr);


    //通过样式来显示图片
    ui->head_lb->setStyleSheet("border-radius:75px;border-image:url(./face.jpg);");

    if(!employeeID.isEmpty())
    ui->Success_widget->show();
}

void MainWindow::initConnections()
{
    //QTcpSocket当断开连接的时候会发送disconnected信号,连接成功会发送connected
    // 连接信号槽
    connect(&m_socket, &QTcpSocket::disconnected, this, [this]() {
        qDebug() << "Disconnected from server. Starting reconnect timer...";
        m_timer.start(5000); // 5 秒后重试
    });

    connect(&m_socket, &QTcpSocket::connected, this, [this]() {
        qDebug() << "Connected to server.";
        m_timer.stop(); // 停止定时器
    });


    connect(&m_socket,&QTcpSocket::readyRead,this,&MainWindow::recv_data);

    connect(&m_socket, &QTcpSocket::errorOccurred, this, [this](QAbstractSocket::SocketError error) {
        qDebug() << "Socket error:" << m_socket.errorString();
        // 可以在这里添加重试逻辑或提示用户
    });

    connect(&m_timer, &QTimer::timeout, this, [this]() {
        attemptConnection();
    });

    // 初始连接尝试
    attemptConnection();
}

void MainWindow::attemptConnection()
{
    if (m_socket.state() != QAbstractSocket::ConnectedState) {
        qDebug() << "Attempting to connect to server...";
        m_socket.connectToHost("192.168.88.234", 9999);

        // 设置连接超时
        QTimer::singleShot(10000, this, [this]() {
            if (m_socket.state() != QAbstractSocket::ConnectedState) {
                qDebug() << "Connection timed out.";
                m_socket.abort(); // 中止连接
            }
        });
    }
}
